#ifndef GUI_H
#define GUI_H



#include "widget_begin.h"
#include "widget_buy.h"
#include "widget_setup.h"
#include "widget_play.h"
#include "init.h"

#include <queue>
#include <map>
#include <string>
#include <QtGui>
#include <QSound>
//#include <QObject>



class begin_widget;
class setup_widget;
class buy_widget;
class play_widget;

class pre_move_info;
class pre_fire_info;
class pre_buy_info;
class pre_sell_info;



//!	Class containing all graphics used in the game
class g_graphics
{

public:

	//! @brief Constructor loads all graphics
	g_graphics();
	//! @brief Destructor deletes all graphics
	~g_graphics();

	/** @brief	Converts numbers to color name
	*	uses col[] array
	*	@param	x number to convert, constraint: x < "MAX_PL"
	*	@return	color name
	*/
	std::string get_color( unsigned int x );
	/** @brief	Converts numbers to QColor
	*	uses qcol[] array
	*	@param	x number to convert, constraint: x < "MAX_PL"
	*	@return	pointer to QColor
	*/
	QColor* get_QColor( unsigned int x );

	/** @brief Loads resources for unit
	*	@param name name of the unit
	*	@param icons vector of file names for each color and selected/unselected status
	*	@param sound_f filename of the sound for the unit
	*/
	void set_new_units_resources( string name, std::vector< std::pair< string, string > >& icons, string sound_f ); 

	//! path pixmap
	QPixmap* p;

	//! fire line style
	QPen* fire;

	//! map_background
	QBrush* map_background;

	//! array of unit's pixmaps < name < normal, selected > >
	std::map< std::string, std::map< std::string, std::pair< QPixmap*, QPixmap* > > > units_pixmaps;
	//! array of terrain pixmaps < number, pixmap >
	std::map< unsigned int, QPixmap* > terrain_pixmaps;
	//! array of bonus pixmaps < name, pixmap >
	std::map< std::string, QPixmap* > bonus_pixmaps;
	//! array of unit's sounds < name, sound >
	std::map< std::string, std::map< std::string, QSound* > > units_sounds;
	//! array of beginning pixmaps < color, pixmap >
	std::map< std::string, QPixmap* > begin_pixmaps;


private:

	//! array for converting number of color to name
	std::string* col;
	//! array for converting number of color to QColor
	QColor** qcol;

};


//TODO
class MyQScrollArea: public QScrollArea
{

public:

	MyQScrollArea( QWidget* parent = 0 ): QScrollArea( parent ) {};

	void setSizeHint( QSize s );
    virtual QSize sizeHint() const;


private:

	QSize size;

};



//! @brief Main gui window
class gui: public QMainWindow
{

public:

	/**	@brief Constructor creates the window, sets menu bar and begin_widget as the central widget
	*	@param parent Qt parent of the widget
	*	@param flags Qt flags
	*/
	gui( QWidget* parent = 0, Qt::WFlags flags = 0 );
	//! @brief Cleans all unnecessary gui items
	~gui();

	//! pinter to begin_widget
	begin_widget* begin_w;
	//! pinter to setup_widget
	setup_widget* setup_w;
	//! pinter to buy_widget
	buy_widget* buy_w;
	//! pointer to play_widget
	play_widget* play_w;
	
};



//! @brief Class for controlling the whole gui
class game_gui
{

public:

	/**	@brief	Function for obaining the singleton
	*	@return	pointer to the singleton
	*/
	static game_gui* get_instance();
	//! @brief Loads all graphics to g_graphics class
	void get_graphics();
	//! @brief Creates gui class
	void create_gui();

	/** @brief Function called at the end of the game
	*	@param won_p winning player, constraint: won_p != 0
	*/
	void show_game_end( player* won_p );

	/** @brief Shows sell event in gui
	*	@param u unit to sell
	*	@param psi some aditional information needed for visualising the event
	*/
	void show_sell( unit* u, pre_sell_info* psi );
	/** @brief Shows buy event in gui
	*	@param u u unit to buy
	*	@param x x coordinate where to place the unit, constraint: x < map->size_x
	*	@param y y coordinate where to place the unit, constraint: y < map->size_y
	*	@param pbi some aditional information needed for visualising the event
	*/
	void show_buy( unit* u, unsigned int x, unsigned int y, pre_buy_info* pbi );
	/** @brief Shows move event in gui
	*	@param moving unit
	*	@param x x coordinate, where it moves, constraint: x < map->size_x
	*	@param y y coordinate, where it moves, constraint: y < map->size_y
	*	@param pmi some aditional information needed for visualising the event
	*/
	void show_move( unit* u, unsigned int x, unsigned int y, pre_move_info* pmi );
	/** @brief Shows fire event in gui
	*	@param u attacking unit
	*	@param x x coordinate, where it attacks, constraint: x < map->size_x
	*	@param y y coordinate, where it attacks, constraint: y < map->size_y
	*	@param pfi some aditional information needed for visualising the event
	*/
	void show_fire( unit* u, unsigned int x, unsigned int y, pre_fire_info* pfi );
	//! @brief Shows nex turn event in gui
	void show_next_turn();
	/** @brief Shows pause event - changes relevant buttons
	*	@param paused true if pause, false if continue
	*/
	void set_paused( bool paused );
	

	//! pointer to gui class
	gui* g;
	//! pointer to g_graphics class
	g_graphics* graphics;


	int x;


private:

	game_gui( int _x ): x( _x )
	{
		g = 0;
		graphics = 0;
	};
	game_gui( const game_gui& );
	game_gui& operator=( const game_gui& x );

};



//! @brief Class containing some aditional information needed for visualising the move event
class pre_move_info
{

public:

	/** @brief Constructor stores all required information
	*	@param u moving unit, constraint: u != 0
	*	@param x x coordinate of the destination, constraint: x < map->size_x
	*	@param y y coordinate of the destination, constraint: y < map->size_y
	*/
	pre_move_info( unit* u, unsigned int x, unsigned int y );
	
	//! original x coordinate of the place before the movement
	unsigned int ox;
	//! original y coordinate of the place before the movement
	unsigned int oy;
	//! path of the movement
	std::queue< std::pair< unsigned int, unsigned int > >* path;

};



//! @brief Class containing some aditional information needed for visualising the fire event
class pre_fire_info
{

public:

	/** @brief Constructor stores all required information
	*	@param u attacking unit, constraint: u != 0
	*	@param x x coordinate of the target, constraint: x < map->size_x
	*	@param y y coordinate of the target, constraint: y < map->size_y
	*/
	pre_fire_info( unit* u, unsigned int x, unsigned int y );

	//! target was also selected unit
	bool s;

};



//! @brief Class containing some aditional information needed for visualising the buy event - not used in this gui
class pre_buy_info
{

public:

	/** @brief Constructor stores all required information
	*	@param u unit to buy, constraint: u != 0
	*	@param x x coordinate where to place the unit, constraint: x < map->size_x
	*	@param y y coordinate where to place the unit, constraint: y < map->size_y
	*/
	pre_buy_info( unit* u, unsigned int x, unsigned int y );

};



//! @brief Class containing some aditional information needed for visualising the sell event
class pre_sell_info
{

public:

	/** @brief Constructor stores all required information
	*	@param u unit to sell, constraint: u != 0
	*/
	pre_sell_info( unit* u );

	//! x coordinate of the unit
	unsigned int ox;
	//! y coordinate of the unit
	unsigned int oy;

};



#endif
